/**
 * 
 */
package utils;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * @author acidflow
 *
 */
public class ClientConfiguration {

	private String ipClient;
	private int portClient;
	private String hashEncryption;
	private int piecesSize;
	private long maxSizeData;
	private long nbConnectionMax;
	private String seedPath;
	private String leechPath;
	private long peersUpdateTime;
	
	private String ipTracker;
	private int portTracker;
	private long trackerUpdateTime;
	
	


	public ClientConfiguration(){
		DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
		domFactory.setNamespaceAware(true); 
		DocumentBuilder builder;
		try {
			builder = domFactory.newDocumentBuilder();
			Document doc = builder.parse("resources/config.xml");
			this.configure(doc);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
	}
	
	public ClientConfiguration(String pathToConfigFile){
		DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
		domFactory.setNamespaceAware(true); 
		DocumentBuilder builder;
		try {
			builder = domFactory.newDocumentBuilder();
			Document doc = builder.parse(pathToConfigFile);
			this.configure(doc);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
	}
	
	private void configure(Document doc) throws XPathExpressionException{
		this.setIPClient(doc);
		this.setPortClient(doc);
		this.setHashEncryption(doc);
		this.setSeedPath(doc);
		this.setPiecesSize(doc);
		this.setIPTracker(doc);
		this.setPortTracker(doc);
		this.setLeechPath(doc);
		this.setMaxSizeData(doc);
		this.setNbConnectionMax(doc);
		this.setTrackerUpdateTime(doc);
		this.setPeersUpdateTime(doc);
	}


	private void setPortClient(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/port-client/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.portClient = Integer.parseInt(portclientNode.item(0).getNodeValue());
	}
	
	private void setMaxSizeData(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/max-size-data/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.maxSizeData = Integer.parseInt(portclientNode.item(0).getNodeValue());
	}
	
	private void setNbConnectionMax(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/max-connections/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.nbConnectionMax = Integer.parseInt(portclientNode.item(0).getNodeValue());
	}
	
	private void setLeechPath(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/leech-path/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.leechPath = portclientNode.item(0).getNodeValue();
	}
	
	private void setPeersUpdateTime(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/peer-update-time/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.peersUpdateTime = Integer.parseInt(portclientNode.item(0).getNodeValue());
	}
	
	private void setTrackerUpdateTime(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/tracker-update-time/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.trackerUpdateTime = Integer.parseInt(portclientNode.item(0).getNodeValue());
	}
	
	private void setIPClient(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/ip-client/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.ipClient = portclientNode.item(0).getNodeValue();
	}
	
	private void setHashEncryption(Document doc) throws XPathExpressionException{
		// XPath Query for encryption
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression hashencryption = xpath.compile("/configuration-pony2pony/hash-encryption/text()");
		Object result1 = hashencryption.evaluate(doc, XPathConstants.NODESET);
		NodeList nodeshashencryptionnode = (NodeList) result1;
		this.hashEncryption = nodeshashencryptionnode.item(0).getNodeValue();
	}
	
	private void setPiecesSize(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/pieces-size/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.piecesSize = Integer.parseInt(portclientNode.item(0).getNodeValue());
	}
	
	private void setSeedPath(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/seed-path/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.seedPath = portclientNode.item(0).getNodeValue();
	}
	
	private void setPortTracker(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/port-tracker/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.portTracker = Integer.parseInt(portclientNode.item(0).getNodeValue());
	}
	
	private void setIPTracker(Document doc) throws XPathExpressionException{
		// XPath Query for client port
		XPath xpath = XPathFactory.newInstance().newXPath();
		XPathExpression portclient = xpath.compile("/configuration-pony2pony/ip-tracker/text()");
		Object result = portclient.evaluate(doc, XPathConstants.NODESET);
		NodeList portclientNode = (NodeList) result;
		this.ipTracker = portclientNode.item(0).getNodeValue();
	}
	


	/**
	 * @return the portClient
	 */
	public int getPortClient() {
		return portClient;
	}

	/**
	 * @return the hashEncryption
	 */
	public String getHashEncryption() {
		return hashEncryption;
	}

	/**
	 * @return the ipClient
	 */
	public String getIpClient() {
		return ipClient;
	}

	/**
	 * @return the ipTracker
	 */
	public String getIpTracker() {
		return ipTracker;
	}

	/**
	 * @return the portTracker
	 */
	public int getPortTracker() {
		return portTracker;
	}
	
	/**
	 * @return the piecesSize
	 */
	public final int getPiecesSize() {
		return piecesSize;
	}

	/**
	 * @return the seedPath
	 */
	public final String getSeedPath() {
		return seedPath;
	}
	
	/**
	 * @return the maxSizeData
	 */
	public final long getMaxSizeData() {
		return maxSizeData;
	}

	/**
	 * @return the nbConnectionMax
	 */
	public final long getNbConnectionMax() {
		return nbConnectionMax;
	}

	/**
	 * @return the leechPath
	 */
	public final String getLeechPath() {
		return leechPath;
	}

	/**
	 * @return the peersUpdateTime
	 */
	public final long getPeersUpdateTime() {
		return peersUpdateTime;
	}

	/**
	 * @return the trackerUpdateTime
	 */
	public final long getTrackerUpdateTime() {
		return trackerUpdateTime;
	}
}
